#ifndef __WIDGET_H__
#define __WIDGET_H__

#include <windows.h>
#include <stdint.h>

// define the EXPORT depending if the compiling is building for linking
// a dll, linking into a dll or linking as static
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#elif BUILD_STATIC
#define EXPORT
#else
#define EXPORT __declspec(dllimport)
#endif

// define main function
#ifdef BUILD_STATIC
#define main(ARGC,ARGV) __main__(ARGC,ARGV)
#else
#define main(ARGC,ARGV) __main__(ARGC,ARGV);\
int WINAPI WinMain(HINSTANCE inst, HINSTANCE preinst, LPSTR cmdline,\
INT cmdshow){_WinMain(inst,preinst,cmdline,cmdshow,__main__);}\
int __main__(ARGC,ARGV)
#endif

#include "delegate.h"

typedef struct widget
{
    // handle to its window
    HWND hwnd;
    // pointer to its parent
    struct widget *parent;
    // coordinates and size
    int32_t x;
    int32_t y;
    uint32_t width;
    uint32_t height;
    // string giving the widget name
    char *text;
    // extended information
    void *ext;
    // callback function
    // function to call to free the widgets memory
    void (*free)(struct widget*);
    // called if the window have been closed
    void (*close)(struct widget*);
    // called when the screen need to be redraw
    void (*paint)(struct widget*,HDC);
    // mouse event
    void (*mouse_move)(struct widget*,int32_t,int32_t,uint32_t);
    void (*lbutton_down)(struct widget*,int32_t,int32_t,uint32_t);
    void (*lbutton_up)(struct widget*,int32_t,int32_t,uint32_t);
    void (*rbutton_down)(struct widget*,int32_t,int32_t,uint32_t);
    void (*rbutton_up)(struct widget*,int32_t,int32_t,uint32_t);
    void (*mouse_leave)(struct widget*);
    // keyboard event
    void (*key_down)(struct widget*,uint32_t);
    void (*key_up)(struct widget*,uint32_t);
} widget_t;

/*! Create a widget with the given coordinates and size
 *
 * \param parent: pointer to its parent, NULL if this is the parent.
 * \param x: coordinate
 * \param y: coordinate
 * \param width: size
 * \param height: size
 * \return pointer to the created widget
 *
 * \note if the widget is a parent ie. (parent=NULL) giving a negative
 * value for x or y coordinate put the widget in center of the screen.
 */
EXPORT widget_t *create_widget(widget_t*,int32_t,int32_t,
                               uint32_t,uint32_t);

/*! Free the widget from the memory
 *
 * \param self: pointer to its widget
 *
 * \note The programmer do not need to free memory for widget at then end of
 * the program, this is done automaticaly.
 */
void widget_free(widget_t*);

/*! Default close callback function, called when the widget closes.
 *
 * \param self: pointer to its widget
 */
void widget_close(widget_t*);

/*! Default paint callback function, called when widget need redrawing.
 *
 * \param self: pointer to its widget
 */
void widget_paint(widget_t*,HDC);

/*! Default mouse move callback function, called when the mouse have moved
 *  above the widget
 *
 * \param self: pointer to its widget 
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag, indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void widget_mouse_move(widget_t*,int32_t,int32_t,uint32_t);

/*! Default mouse left button callback function, called when the user have
 *  pressed teh left mouse button.
 *
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void widget_lbutton_down(widget_t*,int32_t,int32_t,uint32_t);

/*! Default mouse left button callback function, called when the user have
 *  released the left mouse button.
 *
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void widget_lbutton_up(widget_t*,int32_t,int32_t,uint32_t);

/*! Default mouse right button callback function, called when the user have
 *  pressed the right mouse button.
 *
 * \param self: pointer to its self
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */
void widget_rbutton_down(widget_t*,int32_t,int32_t,uint32_t);

/*! Default mouse right button callback function, called when the user have
 *  released the right mouse button.
 * 
 * \param self: pointer to its widget
 * \param x: mouse coordinate
 * \param y: mouse coordinate
 * \param flag: indicate if various virtual key(s) are down:
 *        MK_CONTROL: CTRL key is down
 *        MK_LBUTTON: left mouse button is down
 *        MK_MBUTTON: middle mouse button is down
 *        MK_RBUTTON: right mouse button is down
 *        MK_SHIFT: SHIFT key is down
 */

void widget_rbutton_up(widget_t*,int32_t,int32_t,uint32_t);

/*! Default key button down callback function, called when the user have
 *  presed a key on the key board.
 *
 * \param self: pointer to its widget
 * \param vkey: virtual key pressed (ex. VK_A or VK_ESCAPE)
 */
void widget_key_down(widget_t*,uint32_t);

/*! Default key button up callback function, called when the user have
 *  released a key on the key board.
 *
 *  \param self: pointer to its widget
 *  \param vkey: virtual key released (ex. VK_A or VK_ESCAPE)
 */
void widget_key_up(widget_t*,uint32_t);

/*! Default mouse leave callback function, called when the mouse leaves the
 *  window
 *
 * \param self: widget pointer to its widget
 */
void widget_mouse_leave(widget_t*);

#endif // __WIDGET_H__

